#include "spi_api.h"
#include "devmem2.h"

int spi_init(int *spi_fd)
{
    SPI_MODE mode = SPI_MODE_0;      //SPI模式0(CPOL=0， CPHA=0)
    int bits = 8;               //数据位数
    int delay = 0;              //延迟(ns)
    SPI_SPEED speed;

    /*校验设备是否打开*/
    if(*spi_fd > 0)
    {
        printf("SPI device is already init");
        return -1;
    }

    /*打开设备*/
    *spi_fd = open(SPI_DEVICE_PATH, O_RDWR);
    if(*spi_fd < 0){
        perror("Failed to open SPI device");
        return -1;
    }

    /*设置模式*/
    mode = SPIMODE3;
    if (ioctl(*spi_fd, SPI_IOC_WR_MODE, &mode) < 0)
    {
        perror("Failed to set spi mode");
        close(*spi_fd);
        return -1;
    }

    /*设置数据位字长*/
    if(ioctl(*spi_fd, SPI_IOC_WR_BITS_PER_WORD, &bits) < 0){
        perror("Failed to set bits per word");
        close(*spi_fd);
        return -1;
    }

    /*设置最大传输速率*/
    speed = (u_int32_t)S_5_00M;
    if(ioctl(*spi_fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed) < 0){
        perror("Failed to set SPI speed");
        close(*spi_fd);
        return -1;
    }

    printf("spi mode:0x%x\n", mode);
    printf("bits per word: %d\n", bits);
    printf("max speed    : %d Hz (%d KHz)\n", speed, speed/1000);
    printf("Successfully to init spi %s, fd_spi = %d\n", SPI_DEVICE_PATH, *spi_fd);

    return 0;
}

int spi_uninit(int *spi_fd)
{
    int ret;
 
    ret = close(*spi_fd);//关闭spi设备
    if (0 != ret)
    {
        printf("Failed to uninit spi, ret = %d\n", ret);
    }      
    else
    {
        *spi_fd = -1;
        printf("Successfully to uninit spi, ret = %d\n", ret); 
    }
        
    return 0;
}

int spi_remap0()
{
    devmem_gpio_remap(0x208, 16, 0);         //SPI0_CSN0
    devmem_gpio_remap(0x208, 12, 0);         //SPI0_SCK
    devmem_gpio_remap(0x208, 8, 0);          //SPI0_SO
    devmem_gpio_remap(0x208, 4, 0);          //SPI0_CI
}

int spi_remap1()
{
    devmem_gpio_remap(0x210, 0, 1);         //SPI1_CSN0
    devmem_gpio_remap(0x214, 28, 1);         //SPI1_SCK
    devmem_gpio_remap(0x214, 24, 1);          //SPI1_SO
    devmem_gpio_remap(0x214, 20, 1);          //SPI1_CI
}

int spi0_remap2gpio()
{
    devmem_gpio_remap(0x208, 16, 1);         //SPI0_CSN0
    devmem_gpio_remap(0x208, 12, 1);         //SPI0_SCK
    devmem_gpio_remap(0x208, 8, 1);          //SPI0_SO
    devmem_gpio_remap(0x208, 4, 1);          //SPI0_CI
}